#pragma once
#include "AudioHost.h"
#include "dsoundoutput.h"
#include "WavVstHost.h"

class CAudioHostForDS :
	protected CDsoundOutput,
	public CAudioHost
{
protected:
	enum OUTPUT_DRIVER_TYPE{
		DIRECT_SOUND,
		KERNEL_STREAM,
		CORE_AUDIO
	};
public:
	CAudioHostForDS(void);
	~CAudioHostForDS(void);
	
protected:
	GUID guidCDev[16];

	OUTPUT_DRIVER_TYPE	m_eDrvType;
	int					m_nCDevs;
	char				m_pszCDevNames[16][128];
	int					m_iCurCDev;
	CWavVstHost**		m_pVSTArray;
	HANDLE				m_hThread;
	int					m_nBufferSize;
	int					m_iInChannels;
	int					m_nVolume;
	int					m_nVST;
	const int			MAX_BUFFER_SIZE;
	const int			MIN_BUFFER_SIZE;
	CRITICAL_SECTION	m_cs;
	BOOL				m_fVstChanged;

	HANDLE m_hCapBufferEvent[2];
	HANDLE m_hCtlEvent[2];//Control Events.

	DSCBUFFERDESC m_dscbdesc; 
	LPDIRECTSOUNDCAPTURE8 m_pDSC;
	LPDIRECTSOUNDCAPTUREBUFFER m_pDscb;
	LPDIRECTSOUNDCAPTUREBUFFER8 m_pDscb8;
	
/////////////////////////////////////////////
	static INT_PTR CALLBACK DSoundEnumCallbackC( GUID* pGUID, TCHAR* strDesc, TCHAR* strDrvName,VOID* pContext );
	BOOL Init();
	void Deinit();
	static DWORD WINAPI CreateWorkThread(LPVOID pParam);
	DWORD DoWork();
	
/////////////////////////////////////////////
public:

	int GetListenDeviceCount(void){return m_nLDevs;};
	int GetCaptureDeviceCount(void){return m_nCDevs;};
	char* GetListenDeviceName(int i)
	{
		if(i>=0&&i<m_nLDevs)
			return m_pszLDevNames[i];
		return NULL;
	};
	char* GetCaptureDeviceName(int i)
	{
		if(i>=0&&i<m_nCDevs)
			return m_pszCDevNames[i];
		return NULL;
	};
	int GetCurrentListenDevice(void){return m_iCurLDev;};
	int GetCurrentCaptureDevice(void){return m_iCurCDev;};
	BOOL UseDirectSoundOutput(BOOL fUseDirectSoundOutput){return TRUE;};
	int GetBufferSize(){return m_nBufferSize;};
	int GetVolume(void){return m_nVolume;};

	BOOL SetCurrentListenDevice(int i);
	BOOL SetCurrentListenDeviceByName(char* szDeviceName);
	BOOL SetCurrentCaptureDevice(int i);
	BOOL SetCurrentCaptureDeviceByName(char* szDeviceName);

	BOOL Start(void);
	void Stop(void);
	
	BOOL SetVstEffect(CWavVstHost** pVSTArray,int nCount);

	BOOL SetBufferSize(int size);
	int GetBufferSizeBySampleCount(){return m_nBufferSize/m_wfx.Format.nBlockAlign;};
	BOOL SetBufferSizeBySampleCount(int samples){return SetBufferSize(samples*m_wfx.Format.nBlockAlign);};
	int SetVolume(int Vol);//0-100
	BOOL SetFormat(WAVEFORMATEX* pwfx);
	void GetFormat(WAVEFORMATEX* pwfx);
};
